home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 8: LINUX Games / Linux Cubed Series 8 - LINUX Games.iso / games / torus-sr.tar / torus-sr / torus / main.c < prev    next >
C/C++ Source or Header  |  1992-03-06  |  9KB  |  529 lines

  1. /*
  2.  *    R O B O T S   ( T O R U S )
  3.  *
  4.  *    The game of robots.
  5.  *    History:
  6.  *    Original Implementation
  7.  *        Allan Black <allan@cs.strath.ac.uk>
  8.  *    Updated for fast robots, moveable heaps, ROBOTOPTS
  9.  *    antimatter, v7/sys5/4.2 portability etc.
  10.  *        Graeme Lunt <gal@cs.nott.ac.uk>
  11.  *        Julian Onions <jpo@cs.nott.ac.uk>
  12.  *    Topological modifications:
  13.  *        Tad White <tadpole@math.ucla.edu>
  14.  *
  15.  * Provided free as long as you don't make money from it!
  16.  */
  17.  
  18. # include "robots.h"
  19.  
  20. char    whoami[MAXSTR];
  21. char    my_user_name[MAXSTR];
  22. char    cmd_ch;
  23.  
  24. bool    dead = FALSE;
  25. bool    last_stand;
  26. bool    show_highscore = TRUE;
  27. bool    adjacent, first_move, bad_move, waiting;
  28. bool    moveable_heaps = TRUE;
  29. bool    hsew = TRUE;
  30. bool    vsew = TRUE;
  31. bool    toral = TRUE;
  32. bool    hrev = FALSE;
  33. bool    vrev = FALSE;
  34. bool    wimpy = FALSE;
  35. bool    all_moves = FALSE;
  36. bool    continuous = FALSE;
  37.  
  38. int    my_x, my_y;
  39. int    new_x, new_y;
  40. int    level = 0;
  41. int    free_teleports = 0;
  42. int    old_free;
  43. int    free_per_level = 1;
  44. int    count;
  45. int    dots = 0;
  46. int    robot_value = MIN_VALUE;
  47. int    max_robots = MIN_ROBOTS;
  48. int    nrobots_alive;
  49. int    scrap_heaps = 1;  /* to allow for first level */
  50.  
  51. long    score = 0;
  52. long    seed;
  53.  
  54. # ifdef TIOCSLTC
  55. struct ltchars    ltc;
  56. char    dsusp;
  57. # endif TIOCSLTC
  58.  
  59. # ifdef TURBOC
  60. int
  61. #elif linux
  62. void
  63. #endif
  64. r_interrupt();
  65.  
  66. # define    TERM_UNINIT    00
  67. # define    TERM_CURSES    01
  68. # define    TERM_LTC    02
  69.  
  70. int    term_state = TERM_UNINIT;    /* cuts out some race conditions */
  71. char    *getenv();
  72. # ifndef TURBOC /* rfs */
  73. #ifdef linux
  74. extern struct    passwd    *EXFUN(getpwuid,(uid_t  __uid));
  75. #else
  76. extern struct passwd *getpwuid();
  77. #endif
  78. char    _obuf[BUFSIZ];
  79. # endif
  80.  
  81. main(argc,argv)
  82.      int argc;
  83.      char *argv[];
  84. {
  85. # ifndef TURBOC /* rfs */
  86.   register struct passwd *pass;
  87. # endif
  88.  
  89.   register char *x;
  90.   int i;
  91.  
  92. # ifndef TURBOC /* rfs */
  93.   setbuf(stdout, _obuf);
  94. # endif
  95.   if(argc > 1)
  96.     for(i=1;i<argc;i++) {
  97.       if(argv[i][0] == '-')
  98.     switch(argv[i][1]) {
  99.     case 's':
  100.       show_highscore = TRUE;
  101.       scoring(FALSE);
  102.       exit(0);
  103.       break;
  104.     case 'h':
  105.       hsew = FALSE;
  106.       /* hrev = TRUE; */
  107.       break;
  108.     case 'v':
  109.       vsew = FALSE;
  110.       /* vrev = TRUE; */
  111.       break;
  112.     case 'w':
  113.       wimpy = TRUE;
  114.       break;
  115.     case 'c':
  116.       continuous = FALSE;
  117.       break;
  118.     }
  119.       if(argv[i][0] == '+') {
  120.     switch(argv[i][1]) {
  121.     case 'h':
  122.       hsew = TRUE;
  123.       hrev = FALSE;
  124.       break;
  125.     case 'v':
  126.       vsew = TRUE;
  127.       vrev = FALSE;
  128.       break;
  129.     case 'w':
  130.       wimpy = TRUE;
  131.       break;
  132.     case 'c':
  133.       continuous = TRUE;
  134.       break;
  135.     }
  136.       }
  137.       if (argv[i][0] == '0') {
  138.     switch(argv[i][1]) {
  139.     case 'h':
  140.       hsew = FALSE;
  141.       hrev = FALSE;
  142.       break;
  143.     case 'v':
  144.       vsew = FALSE;
  145.       vrev = FALSE;
  146.       break;
  147.     }
  148.       }
  149.     }
  150. # ifdef TURBOC /* rfs */
  151.   if (strcmp(x=getenv("USERNAME"),"")==0) x="ANON";
  152. # else
  153.   if((pass = getpwuid(getuid())) == 0) {
  154.     x = "ANON";
  155.   } else {
  156.     x = pass->pw_name;
  157.   }
  158. # endif
  159.   (void) strcpy(my_user_name, x);
  160.   (void) strcpy(whoami,x);
  161.   if((x = getenv(ROBOTOPTS)) != NULL && *x != '\0')
  162.     get_robot_opts(x);
  163.   seed = time((time_t *)0)+getuid();
  164. # ifndef TURBOC /* rfs */
  165.   (void) signal(SIGQUIT,r_interrupt);
  166.   (void) signal(SIGINT,r_interrupt);
  167. # endif
  168.   if( initscr() == ERR) {
  169.     fprintf(stderr, "Curses won't initialize - seek a guru\n");
  170.     quit();
  171.   }
  172.   term_state |= TERM_CURSES;
  173.   crmode();
  174.   noecho();
  175. # ifdef TIOCSLTC
  176.   (void) ioctl(1,TIOCGLTC,<c);
  177.   dsusp = ltc.t_dsuspc;
  178.   ltc.t_dsuspc = ltc.t_suspc;
  179.   (void) ioctl(1,TIOCSLTC,<c);
  180.   term_state |= TERM_LTC;
  181. # endif TIOCSLTC
  182. restart:  
  183.   dead = FALSE;
  184.   free_teleports = 0;
  185.   level = 0;
  186.   free_per_level = 1;
  187.   scrap_heaps = 1;
  188.   score = 0;
  189.   robot_value = MIN_VALUE;
  190.   max_robots = MIN_ROBOTS;
  191.   for(;;) {
  192.     count = 0;
  193.     adjacent = FALSE;
  194.     waiting = FALSE;
  195.     last_stand = FALSE;
  196.     old_free = -1;
  197.     if(rnd(free_per_level) < free_teleports) {
  198.       free_per_level++;
  199.       if(free_per_level > MAX_FREE) free_per_level = MAX_FREE;
  200.     }
  201.     free_teleports += free_per_level;
  202.     leaveok(stdscr,FALSE);
  203.     draw_screen();
  204.     put_robots();
  205.     do {
  206.       my_x = rndx();
  207.       my_y = rndy();
  208.       move(my_y,my_x);
  209.     } while(inch() != ' ');
  210.     addch(ME);
  211.     if (dots) put_dots();
  212.     for(;;) {
  213.       scorer();
  214.       if(nrobots_alive == 0) break;
  215.       command();
  216.       for(i=1;i<=FASTEST;i++)
  217.     robots(i);
  218.       if(dead) { munch(); goto restart; }
  219.     }
  220.     msg("%d robots are now %d scrap heaps",max_robots, scrap_heaps);
  221.     leaveok(stdscr,FALSE);
  222.     move(my_y,my_x);
  223.     refresh();
  224.     (void) readchar();
  225.     level++;
  226.   }
  227. }
  228.  
  229. draw_screen()
  230. {
  231.     register int x, y;
  232.     clear();
  233.     for(y = 1; y < LINES-2; y++) {
  234.         mvaddch(y,0,VERT);
  235.         mvaddch(y,COLS-1,VERT);
  236.     }
  237.     for(x = 0; x < COLS; x++) {
  238.         mvaddch(0,x,HORIZ);
  239.         mvaddch(LINES-2,x,HORIZ);
  240.     }
  241. }
  242.  
  243. readchar()
  244. {
  245. # ifdef TURBOC /* rfs */
  246.     return getch();
  247. # else
  248.     static char buf[1];
  249.     extern int errno;
  250.  
  251.     while(read(0,buf,1) != 1)
  252.         if( errno != EINTR) {
  253.             scoring(TRUE);
  254.             quit();
  255.         }
  256.     return(buf[0]);
  257. # endif
  258. }
  259.  
  260. put_dots()
  261. {
  262.     register int x, y;
  263.     for(x = my_x-dots; x <= my_x+dots; x++) {
  264.         for(y = my_y-dots; y <= my_y+dots; y++) {
  265.             tmove(y,x);
  266.             if(inch() == ' ') addch(DOT);
  267.         }
  268.     }
  269. }
  270.  
  271. erase_dots()
  272. {
  273.     register int x, y;
  274.     for(x = my_x-dots; x <= my_x+dots; x++) {
  275.         for(y = my_y-dots; y <= my_y+dots; y++) {
  276.             tmove(y,x);
  277.             if(inch() == DOT) addch(' ');
  278.         }
  279.     }
  280. }
  281.  
  282. xinc(dir)
  283.     char dir;
  284. {
  285.     switch(dir) {
  286.     case 'h':
  287.     case 'y':
  288.     case 'b':
  289.         return(-1);
  290.     case 'l':
  291.     case 'u':
  292.     case 'n':
  293.         return(1);
  294.     case 'j':
  295.     case 'k':
  296.     default:
  297.         return(0);
  298.     }
  299. }
  300.  
  301. yinc(dir)
  302.     char dir;
  303. {
  304.     switch(dir) {
  305.     case 'k':
  306.     case 'y':
  307.     case 'u':
  308.         return(-1);
  309.     case 'j':
  310.     case 'b':
  311.     case 'n':
  312.         return(1);
  313.     case 'h':
  314.     case 'l':
  315.     default:
  316.         return(0);
  317.     }
  318. }
  319.  
  320. int vbound(y,x)  /* for toral robots:  converts y to lie within boundary */
  321.      int y,x;
  322. {
  323.   register int t_y;
  324.   t_y = y;
  325.   if ( vsew /* ||vrev */ ) {
  326.     if (y >= LINES-2) t_y = y - (LINES-3);
  327.     if (y <= 0) t_y = y + (LINES-3);
  328.   }
  329.   /* if ( (hrev) && ((x >= COLS-1) || (x <= 0)) ) t_y = LINES - 2 - t_y; */
  330.   return(t_y);
  331. }
  332.  
  333. int hbound(y,x)
  334.      int y,x;
  335. {
  336.   register int t_x;
  337.   t_x = x;
  338.   if (hsew /*||hrev*/ ) {
  339.     if (x >= COLS-1) t_x = x - (COLS-2);
  340.     if (x <= 0) t_x = x + (COLS-2);
  341.   }
  342.   /* if ( (vrev) && ((y >= LINES-2) || (y <= 0)) ) t_x = COLS - 1 - t_x; */
  343.   return(t_x);
  344. }
  345.  
  346. tmove(y,x)  /* move with wrap-around, if edge identifications made. */
  347. int y,x;
  348. {
  349.   move(vbound(y,x),hbound(y,x));
  350. }
  351.  
  352. munch()
  353. {
  354.     scorer();
  355.     msg("MUNCH! You're robot food");
  356.     leaveok(stdscr,FALSE);
  357.     mvaddch(my_y,my_x,MUNCH);
  358.     move(my_y,my_x);
  359.     refresh();
  360.     (void) readchar();
  361.     scoring(TRUE);
  362.     if (!continuous) quit();
  363. }
  364.  
  365. quit()
  366. {
  367.     if( term_state & TERM_CURSES ) {
  368.         move(LINES-1,0);
  369.         refresh();
  370.         endwin();
  371.         term_state &= ~ TERM_CURSES;
  372.     }
  373.     putchar('\n');
  374. # ifdef TIOCSLTC
  375.     if( term_state & TERM_LTC ) {
  376.         ltc.t_dsuspc = dsusp;
  377.         (void) ioctl(1,TIOCSLTC,<c);
  378.         term_state &= ~ TERM_LTC;
  379.     }
  380. # endif TIOCSLTC
  381.     (void) signal(SIGINT, SIG_DFL);
  382.     exit(0);
  383. }
  384.  
  385. rndx()
  386. {
  387.     return(rnd(COLS-2)+1);
  388. }
  389.  
  390. rndy()
  391. {
  392.     return(rnd(LINES-3)+1);
  393. }
  394.  
  395. rnd(mod)
  396.     int mod;
  397. {
  398.     if(mod <= 0) return(0);
  399.     return((((seed = seed*11109L+13849L) >> 16) & 0xffffL) % mod);
  400. }
  401.  
  402. /* VARARGS 1 */
  403. msg(message,a1, a2, a3, a4, a5, a6, a7)
  404.     char *message;
  405.     unsigned int a1, a2, a3, a4, a5, a6, a7;
  406. {
  407.     static char msgbuf[1000];
  408.  
  409.     (void) sprintf(msgbuf, message, a1, a2, a3, a4, a5, a6, a7);
  410.     mvaddstr(LINES-1,MSGPOS,msgbuf);
  411.     clrtoeol();
  412.     refresh();
  413. }
  414.  
  415. # ifdef TURBOC /* rfs */
  416. int
  417. #elif linux
  418. void
  419. # endif
  420. r_interrupt()
  421. {
  422.     scoring(FALSE);
  423.     quit();
  424. }
  425.  
  426. /*
  427.  * file locking routines - much nicer under BSD ...
  428.  */
  429.  
  430. # ifdef TURBOC /* rfs */
  431. lk_open(file,mode) /* don't need to lock score files on IBM PCs */
  432. char *file;
  433. int mode;
  434. {
  435.     int    fd;
  436.     if ((fd = open(file, mode, S_IREAD|S_IWRITE)) < 0)  return -1;
  437.     return fd;
  438. }
  439.  
  440. lk_close(fd, fname)
  441. int    fd;
  442. char    *fname;
  443. {
  444.     return close(fd);
  445. }
  446.  
  447. # endif
  448. # if defined(BSD42)
  449. lk_open(file, mode)    /* lock a file using the flock sys call */
  450. char    *file;
  451. int    mode;
  452. {
  453.     int    fd;
  454.  
  455.     if( (fd = open(file, mode)) < 0)
  456.         return -1;
  457.     if( flock(fd, LOCK_EX) < 0)
  458.     {
  459.         (void) close(fd);
  460.         return -1;
  461.     }
  462.     return fd;
  463. }
  464.  
  465. lk_close( fd, file)
  466. int    fd;
  467. char    *file;
  468. {
  469. # ifdef lint
  470.     file = file;    /* now will you shut up lint???? */
  471. # endif
  472.     return close(fd);
  473. }
  474. # else
  475.  
  476. # define    LOCKTIME    (60)    /* 1 minute */
  477. # include    <sys/stat.h>
  478.  
  479. lk_open(file, mode)    /* lock a file by crude means */
  480. char    *file;
  481. int    mode;
  482. {
  483.     char    tfile[128], lfile[128];
  484.     struct    stat stbuf;
  485.     time_t    now;
  486.     int    fd;
  487.  
  488.     (void) sprintf(tfile, "%s.t", file);    /* temp file */
  489.     (void) sprintf(lfile, "%s.l", file);    /* lock file */
  490.  
  491.     if( close(creat(tfile, 0)) < 0)    /* make temp file */
  492.         return -1;
  493.     while( link(tfile, lfile) == -1)    /* now attempt the lock file */
  494.     {
  495.         if( stat(lfile, &stbuf) < 0)
  496.             continue;    /* uhh? -- try again */
  497.         time(&now);
  498.         /* OK - is this file old? */
  499.         if( stbuf.st_mtime + LOCKTIME < now)
  500.             unlink(lfile);    /* ok its old enough - junk it */
  501.         else    sleep(1);    /* snooze ... */
  502.     }
  503.     unlink(tfile);    /* tmp files done its job */
  504.     if((fd = open(file, mode)) < 0) {
  505.         unlink(lfile);
  506.         return -1;
  507.     }
  508.     return fd;
  509. }
  510.  
  511. lk_close(fd, fname)
  512. int    fd;
  513. char    *fname;
  514. {
  515.     char    lfile[128];
  516.  
  517.     (void) sprintf(lfile, "%s.l", fname);    /* recreate the lock file name */
  518.     if( unlink(lfile) == -1) /* blow it away */
  519.         perror(lfile);
  520.     return close(fd);
  521. }
  522. # endif
  523.  
  524. # ifdef TURBOC /* rfs */
  525. int getuid () {
  526.   return 0;
  527.   }
  528. # endif
  529.